package se.topshelf.golftracker.core.domain;

import org.hibernate.annotations.Sort;
import org.hibernate.annotations.SortType;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 *
 */
@Entity
@Table(name = "Course")
public class Course extends BaseEntity implements Comparable<Course>{
    @NotNull
    @ManyToOne
    @JoinColumn(name = "memberClubId")
    private MemberClub memberClub;

    @NotNull  // Name is unique within a member club
    private String name;

    @OneToMany(mappedBy="course")
    @Sort(type = SortType.NATURAL)
    private SortedSet<Hole> holes = new TreeSet<Hole>();

    public Course() {
    }

    public Course(String name) {
        this.name = name;
    }

    public MemberClub getMemberClub() {
        return memberClub;
    }

    // Only for Hibernate Use add on MemberClub
    public void setMemberClub(MemberClub memberClub) {
        this.memberClub = memberClub;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public SortedSet<Hole> getHoles() {
        return holes;
    }

    public void addHole(Hole hole){
       assertNotAlreadyAdded(hole, holes);
        hole.setCourse(this);
        holes.add(hole);
    }

    // Use add instead
    void setHoles(SortedSet<Hole> holes) {
        this.holes = holes;
    }

    @Override
    public String getGuiDescription() {
        return name;
    }

    public int compareTo(Course o) {
        int memberClubCompare = memberClub.compareTo(o.getMemberClub());
        if(memberClubCompare == 0){
            // Tie, check names, should be unique within the club
            return name.compareTo(o.getName());
        }
        return  memberClubCompare;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Course course = (Course) o;

        if (memberClub != null ? !memberClub.equals(course.memberClub) : course.memberClub != null) return false;
        if (name != null ? !name.equals(course.name) : course.name != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = memberClub != null ? memberClub.hashCode() : 0;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append("Course");
        sb.append("{memberClub=").append(memberClub.getGuiDescription());
        sb.append(", name='").append(name).append('\'');
        sb.append('}');
        return sb.toString();
    }
}
